package com.duobaoyu.dby.supply.biz.client.boundary.order.bean.bo;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.duobaoyu.dby.channel.adapter.enums.biz.order.OrderStatusEnum;
import com.duobaoyu.dby.common.core.constant.StringPool;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.builder.DiffBuilder;
import org.apache.commons.lang3.builder.DiffResult;
import org.apache.commons.lang3.builder.Diffable;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 订单明细信息
 *
 * @author chenms
 * @date 2023/10/7 11:58 AM
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class OrderBO implements Serializable, Diffable<Object> {

    /**
     * 渠道编码
     */
    private String channelCode;
    /**
     * 渠道子单号
     */
    private String channelOrderSn;
    /**
     * 渠道父单号
     */
    private String channelOrderParentSn;
    /**
     * 渠道交易单号
     */
    private String channelTradeOrderSn;
    /**
     * 渠道订单实际金额
     */
    private BigDecimal channelOrderRealityAmount;
    /**
     * 渠道订单总金额
     */
    private BigDecimal channelOrderAmount;
    /**
     * 渠道运费
     */
    private BigDecimal channelFreightAmount;
    /**
     * 渠道实际运费
     */
    private BigDecimal channelActualFreightAmount;
    /**
     * 供应链三方交易单号
     */
    private String orderTradeSn;
    /**
     * 订单总金额
     */
    private BigDecimal orderAmount;
    /**
     * 订单类型
     */
    private String orderType;
    /**
     * 业务订单交易号(与供应链订单号一一对应)
     */
    private String bizTradeSn;
    /**
     * 供应链交易单号(与业务订单号一一对应)
     */
    private String supplyTradeSn;
    /**
     * 供应链订单号
     */
    private String orderSn;
    /**
     * 供应链订单号父单号
     */
    private String orderParentSn;
    /**
     * 0:拆单前、1:拆单后
     *
     * @see com.duobaoyu.dby.supply.biz.enums.OrderParentTypeEnum
     */
    private Integer parentType;
    /**
     * 系统内部名称
     */
    private String serverName;
    /**
     * 展示来源渠道
     */
    private String showServerName;
    /**
     * 手机号/充值账号
     */
    private String rechargeAccount;
    /**
     * 下单失败原因
     */
    private String failReason;
    /**
     * 取消原因
     */
    private String cancelReason;
    /**
     * 备注信息
     */
    private String orderRemark;
    /**
     * 订单状态
     */
    private Integer orderStatus;
    /**
     * 订单标签: asyn-异步;sync-同步
     */
    private String orderTag;
    /**
     * 确认订单时间
     */
    private LocalDateTime confirmOrderTime;
    /**
     * 是否允许请求售后
     */
    private Boolean afterSalesAllowed;
    /**
     * 商户ID
     */
    private String mchId;
    /**
     * 用户ID
     */
    private String userId;

    /**
     * 发票状态
     */
    private Integer invoiceStatus;
    /**
     * 状态变更时间
     */
    private LocalDateTime statusChangeTime;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

    /**
     * 订单收货地址
     */
    private OrderAddressBO orderAddress;

    /**
     * 订单商品
     */
    private List<OrderProductBO> orderProductList;

    /**
     * 订单物流
     */
    private List<OrderLogisticsBO> orderLogisticsList;

    /**
     * 订单总额
     */
    public BigDecimal getOrderAmount() {
        if (Objects.nonNull(orderAmount)) {
            return this.orderAmount;
        }
        if (CollectionUtils.isNotEmpty(orderProductList)) {
            return orderProductList.stream().map(OrderProductBO::getPlatformSellAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, NumberUtil::add);
        }
        return this.orderAmount;
    }

    /**
     * 渠道订单实际支付总额
     * @return
     */
    public BigDecimal getChannelOrderRealityAmount() {
        if (Objects.nonNull(channelOrderRealityAmount)) {
            return this.channelOrderRealityAmount;
        }
        if (CollectionUtils.isNotEmpty(orderProductList)) {
            return orderProductList.stream().map(OrderProductBO::getChannelPayAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, NumberUtil::add);
        }
        return this.channelOrderRealityAmount;
    }

    public String removeTag(String orderTag) {
        List<String> split = StrUtil.split(this.orderTag, StringPool.COMMA);
        if (Objects.isNull(split)) {
            return this.orderTag;
        }
        split.remove(orderTag);
        if (!split.isEmpty()) {
            this.orderTag = StrUtil.join(StringPool.COMMA, split);
        } else {
            this.orderTag = StringPool.EMPTY;
        }
        return this.orderTag;
    }

    public String addTag(String orderTag) {
        List<String> split = StrUtil.split(this.orderTag, StringPool.COMMA);
        if (Objects.isNull(split)) {
            this.orderTag = orderTag;
            return this.orderTag;
        }
        split.add(orderTag);
        this.orderTag = StrUtil.join(StringPool.COMMA, split);
        return this.orderTag;
    }

    @Override
    public DiffResult diff(Object obj) {
        DiffBuilder diffBuilder = new DiffBuilder(this, obj, ToStringStyle.SHORT_PREFIX_STYLE);
        if (obj instanceof OrderBO) {
            OrderBO order = (OrderBO) obj;
            diffBuilder.append("订单状态", OrderStatusEnum.getOrderSubStatusDesc(this.orderStatus), OrderStatusEnum.getOrderSubStatusDesc(order.getOrderStatus()));
            diffBuilder.append("供应链三方交易单号", this.getOrderTradeSn(), order.getOrderTradeSn());
            diffBuilder.append("订单标签", this.getOrderTag(), order.getOrderTag());
            diffBuilder.append("渠道订单号", this.getChannelOrderSn(), order.getChannelOrderSn());
            diffBuilder.append("渠道交易号", this.getChannelTradeOrderSn(), order.getChannelTradeOrderSn());
        } else if (obj instanceof UpdateOrderBO) {
            UpdateOrderBO updateOrder = (UpdateOrderBO) obj;
            Optional.ofNullable(updateOrder.getOrderStatus()).ifPresent(item -> diffBuilder.append("订单状态", OrderStatusEnum.getOrderSubStatusDesc(updateOrder.getOrderStatus().getKey()), OrderStatusEnum.getOrderSubStatusDesc(updateOrder.getOrderStatus().getValue())));
            diffBuilder.append("订单标签", this.getOrderTag(), updateOrder.getOrderTag());
            diffBuilder.append("供应链三方交易单号", this.getOrderTradeSn(), updateOrder.getOrderTradeSn());
            diffBuilder.append("渠道订单号", this.getChannelOrderSn(), updateOrder.getChannelOrderSn());
            diffBuilder.append("渠道交易号", this.getChannelTradeOrderSn(), updateOrder.getChannelTradeOrderSn());
            diffBuilder.append("失败原因", this.getFailReason(), updateOrder.getErrorInfo());
        }
        return diffBuilder.build();
    }

    public OrderBO update(UpdateOrderBO updateOrder) {
        if (StrUtil.isNotBlank(updateOrder.getChannelOrderSn())) {
            this.channelOrderSn = updateOrder.getChannelOrderSn();
        }
        if (StrUtil.isNotBlank(updateOrder.getChannelTradeOrderSn())) {
            this.channelTradeOrderSn = updateOrder.getChannelTradeOrderSn();
        }
        this.orderStatus = Optional.ofNullable(updateOrder.getOrderStatus()).map(item->item.getValue()).orElse(this.orderStatus);
        this.afterSalesAllowed = updateOrder.getAfterSalesAllowed();
        return this;
    }
}
